import java.util.*;

public class Leetcode149 {
    static int max = 0;

    public static void main(String[] args) {
        int[][] points = {{7, 3}, {19, 19}, {-16, 3}, {13, 17}, {-18, 1}, {-18, -17}, {13, -3}, {3, 7}, {-11, 12}, {7, 19}, {19, -12}, {20, -18}, {-16, -15}, {-10, -15}, {-16, -18}, {-14, -1}, {18, 10}, {-13, 8}, {7, -5}, {-4, -9}, {-11, 2}, {-9, -9}, {-5, -16}, {10, 14}, {-3, 4}, {1, -20}, {2, 16}, {0, 14}, {-14, 5}, {15, -11}, {3, 11}, {11, -10}, {-1, -7}, {16, 7}, {1, -11}, {-8, -3}, {1, -6}, {19, 7}, {3, 6}, {-1, -2}, {7, -3}, {-6, -8}, {7, 1}, {-15, 12}, {-17, 9}, {19, -9}, {1, 0}, {9, -10}, {6, 20}, {-12, -4}, {-16, -17}, {14, 3}, {0, -1}, {-18, 9}, {-15, 15}, {-3, -15}, {-5, 20}, {15, -14}, {9, -17}, {10, -14}, {-7, -11}, {14, 9}, {1, -1}, {15, 12}, {-5, -1}, {-17, -5}, {15, -2}, {-12, 11}, {19, -18}, {8, 7}, {-5, -3}, {-17, -1}, {-18, 13}, {15, -3}, {4, 18}, {-14, -15}, {15, 8}, {-18, -12}, {-15, 19}, {-9, 16}, {-9, 14}, {-12, -14}, {-2, -20}, {-3, -13}, {10, -7}, {-2, -10}, {9, 10}, {-1, 7}, {-17, -6}, {-15, 20}, {5, -17}, {6, -6}, {-11, -8}};
        System.out.println(maxPoints(points));
    }

    public static int maxPoints(int[][] points) {
        Map<Pair, Set<Pair>> integerMap = new HashMap<>();

        for (int i = 0; i < points.length; i++) {
            for (int j = i + 1; j < points.length; j++) {
                countSlope(points[i][0], points[i][1], points[j][0], points[j][1], integerMap);
            }
        }

        return max;
    }

    private static void countSlope(int x1, int y1, int x2, int y2, Map<Pair, Set<Pair>> integerMap) {
        int xDiff = x1 - x2;
        int yDiff = y1 - y2;
        Pair slope;
        if (xDiff == 0) {
            slope = new Pair(0, Integer.MAX_VALUE);
        } else if (yDiff == 0) {
            slope = new Pair(Integer.MAX_VALUE, 0);
        } else {
            int gcd = gcd(xDiff, yDiff);
            slope = new Pair(xDiff / gcd, yDiff / gcd);
        }

        Set<Pair> set;
        if (integerMap.containsKey(slope)) {
            set = integerMap.get(slope);
        } else {
            set = new HashSet<>();
        }

        set.add(new Pair(x1, y1));
        set.add(new Pair(x2, y2));
        integerMap.put(slope, set);

        if (set.size() > max) {
            System.out.println("key为:" + slope);
            max = set.size();
            System.out.println("~~~~~~~~~");
            set.forEach(System.out::print);
            System.out.println("~~~~~~~~~");
        }
    }

    public static int gcd(int a, int b) {
        return b == 0 ? a : gcd(b, a % b);
    }

    static class Pair {
        int x;
        int y;

        public Pair(int x, int y) {
            this.x = x;
            this.y = y;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (o == null || getClass() != o.getClass()) {
                return false;
            }
            Pair pair = (Pair) o;

            if (this.x == pair.x && this.x == 0) {
                return true;
            }

            if (this.y == pair.y && this.y == 0) {
                return true;
            }
            return x == pair.x && y == pair.y;
        }

        @Override
        public int hashCode() {
            return Objects.hash(x, y);
        }

        @Override
        public String toString() {
            return "Pair{" +
                    "x=" + x +
                    ", y=" + y +
                    '}';
        }
    }

}
